//
// Created by Administrator on 2024/7/4.
//

#ifndef LOG_FACTORY_H
#define LOG_FACTORY_H

#define DEBUG(logger,...) (SPDLOG_LOGGER_DEBUG(logger, __VA_ARGS__))
#define INFO(logger,...) (SPDLOG_LOGGER_INFO(logger, __VA_ARGS__))
#define WARN(logger,...) (SPDLOG_LOGGER_WARN(logger, __VA_ARGS__))
#define ERR(logger,...) (SPDLOG_LOGGER_ERROR(logger, __VA_ARGS__))
#define CRITICAL(logger,...) (SPDLOG_LOGGER_CRITICAL(logger, __VA_ARGS__))

#include <valarray>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/daily_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <unordered_map>
#include <string>

typedef std::shared_ptr<spdlog::logger> Logger;



class JTT809Logger final {
    static inline std::unordered_map<std::string, Logger> *loggers_ = nullptr;
    static inline std::once_flag flag;

    JTT809Logger() = default;

public:
    static Logger& logger(const std::string& module) {
        std::call_once(flag, []{
            loggers_ = new std::unordered_map<std::string, Logger>();
        });

        if (loggers_->contains(module))
            return (*loggers_)[module];

        std::vector<spdlog::sink_ptr> sinks;
        sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
        sinks.push_back(std::make_shared<spdlog::sinks::daily_file_format_sink_mt>("logs/daily.log", 0,0));
        sinks.at(sinks.size()-1)->set_level(spdlog::level::info);
        const auto error_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("logs/error.log", 1048576*5, 20);
        error_sink->set_level(spdlog::level::err);
        sinks.push_back(error_sink);

        auto logger_ = std::make_shared<spdlog::logger>(module,std::begin(sinks), std::end(sinks));
#ifdef DEBUG_BUILD
        logger_->set_level(spdlog::level::info);
        // logger_->debug("You will see this debug message when you switch DEBUG_BUILD on");
#endif
        spdlog::register_logger(logger_);
        logger_->flush_on(spdlog::level::info);
        (*loggers_)[module] = logger_;

        return (*loggers_)[module];
    }

    static Logger& logger() {
        return logger("default");
    }
};

inline extern Logger recorder = JTT809Logger::logger("recorder");

#endif //LOG_FACTORY_H
